
#ifndef _SINGLETON_H_
#define _SINGLETON_H_

#include <stdlib.h>
#include <pthread.h>

namespace trident {

template<typename type_t>
class singleton_t
{
public:
    /**
     * @brief get instance
     * @param type_t
     */
    static type_t& instance()
    {
        pthread_once(&_pthread_once, &singleton_t::init);
        return *_instance;
    }

private:
    /**
     * @brief constructor
     */
    singleton_t();

    /**
     * @brief destructor
     */
    ~singleton_t();

    static void init()
    {
        _instance = new type_t();
        ::atexit(destroy);
    }

    static void destroy()
    {
        if (_instance)
        {
            delete _instance;
            _instance = NULL;
        }
    }

private:
    static pthread_once_t       _pthread_once;
    static type_t*              _instance;
};

template<typename type_t>
pthread_once_t singleton_t<type_t>::_pthread_once = PTHREAD_ONCE_INIT;

template<typename type_t>
type_t* singleton_t<type_t>::_instance = NULL;

} // namespace trident

#endif //_SINGLETON_H_
